package org.jeecg.modules.service.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.common.DateCommon;
import org.jeecg.modules.entity.*;
import org.jeecg.modules.entity.vo.ContractStatisticsVo;
import org.jeecg.modules.entity.vo.DbContractVo;
import org.jeecg.modules.mapper.DbContractMapper;
import org.jeecg.modules.mapper.DbFileMapper;
import org.jeecg.modules.mapper.DbFinanceManageMapper;
import org.jeecg.modules.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: db_contract
 * @Author: jeecg-boot
 * @Date:   2024-06-13
 * @Version: V1.0
 */
@Service
public class DbContractServiceImpl extends ServiceImpl<DbContractMapper, DbContract> implements IDbContractService {
    @Autowired
    private DbContractMapper dbContractMapper;
    @Autowired
    private IDbSeqService dbSeqService;
    @Autowired
    private IDbFileService dbFileService;
    @Autowired
    @Lazy
    private IDbFinanceManageService dbFinanceManageService;
    @Autowired
    @Lazy
    private IDbYearlyPlanService dbYearlyPlanService;
    /**
     *   添加
     *
     * @param dbContract
     * @return
     */
    @Transactional
    public void add(DbContract dbContract) {
        //编号生成
        DbSeq dbSeq = new DbSeq();
        QueryWrapper<DbSeq> queryWrapper = new QueryWrapper<>();
        Date currentDate = new Date();
        String formattedDate = DateCommon.YYYYMMDD.format(currentDate);
        String name = "db_contract"+formattedDate;
        queryWrapper.eq("name",name);
        DbSeq dbSeq1 = dbSeqService.getOne(queryWrapper);
        if(dbSeq1 == null){
            dbSeq.setName(name);
            dbSeq.setSeq(0001);
            String contractId=formattedDate+"0001";
            dbSeqService.save(dbSeq);
            dbContract.setContractId(contractId);
            //插入file_group_id
            updateFileGroupId(dbContract);
            //插入db_finance_manage
            insertFinanceManage(dbContract);
            //修改年度计划进度
            dbYearlyPlanService.addContractUpdateYearPlan(dbContract);
        }else{
            Integer seq = dbSeq1.getSeq();
            seq+=1;
            UpdateWrapper<DbSeq> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("seq",seq).eq("name",dbSeq1.getName());
            dbSeqService.update(dbSeq1,updateWrapper);
            // 使用String.format()来确保序列号是4位数，不足的前面补0
            String seqStr = String.format("%04d", seq);
            String contractId=formattedDate+seqStr;
            dbContract.setContractId(contractId);
            //插入file_group_id
            updateFileGroupId(dbContract);
            //插入db_finance_manage
            insertFinanceManage(dbContract);
            //修改年度计划进度
            dbYearlyPlanService.addContractUpdateYearPlan(dbContract);
        }
    }


    /**
     * 修改财务信息
     * @param dbContract
     */
    @Transactional
    public void updateFinanceManage(DbContract dbContract) {
        UpdateWrapper<DbFinanceManage> updateWrapper = new UpdateWrapper<>();
        QueryWrapper<DbFinanceManage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("contract_id",dbContract.getContractId());
        DbFinanceManage dbFinanceManage = dbFinanceManageService.getOne(queryWrapper);
        BigDecimal receivableAmount = dbContract.getContractAmount().subtract(dbContract.getReturnedAmount());
        updateWrapper.eq("contract_id",dbContract.getContractId())
                .set("name",dbContract.getName())
                .set("cus_name",dbContract.getCusName())
                .set("signature_date",dbContract.getSignatureDate())
                .set("type",dbContract.getType())
                .set("contract_amount",dbContract.getContractAmount())
                .set("receivable_amount",receivableAmount);
        dbFinanceManageService.update(dbFinanceManage,updateWrapper);
    }

    /**
     * 更新文件信息
     * @param dbContract
     */
    @Transactional
    public void updateAndFileById(DbContract dbContract) {
        if(dbContract.getFileIds()==null||dbContract.getFileIds().isEmpty()){
            this.updateById(dbContract);
        }else {
            dbContract.setFileGroupId(null);
            this.updateById(dbContract);
            UpdateWrapper<DbContract> dbContractUpdateWrapper = new UpdateWrapper<>();
            String fileGroupId = "db_contract"+dbContract.getContractId();
            dbContractUpdateWrapper.set("file_group_id",fileGroupId).eq("id",dbContract.getId());
            this.update(dbContract,dbContractUpdateWrapper);
            UpdateWrapper<DbFile> updateWrapper = new UpdateWrapper<>();
            DbFile dbFile = new DbFile();
            updateWrapper.set("group_id", fileGroupId).in("id",dbContract.getFileIds());
            dbFileService.update(dbFile,updateWrapper);
        }
    }

    /**
     *   通过id删除
     *
     * @param id
     * @return
     */
    @Transactional
    public void deleteById(String id) {
        //删除文件
        DbContract dbContract = this.getById(id);
        if(dbContract.getFileGroupId()!=null){
            QueryWrapper<DbFile> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("group_id",dbContract.getFileGroupId());
            List<DbFile> list = dbFileService.list(queryWrapper);
            list.forEach(dbFile -> {
                dbFileService.removeById(dbFile.getId());
            });
        }
        this.removeById(id);
    }

    /**
     *  批量删除
     *
     * @param ids
     * @return
     */
    @Transactional
    public void deleteBatch(String ids) {
        //批量删除文件
        List<String> idList= Arrays.asList(ids.split(","));
        idList.forEach(id -> {
            DbContract dbContract = this.getById(id);
            if(dbContract.getFileGroupId()!=null){
                QueryWrapper<DbFile> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("group_id",dbContract.getFileGroupId());
                List<DbFile> list = dbFileService.list(queryWrapper);
                list.forEach(dbFile -> {
                    dbFileService.removeById(dbFile.getId());
                });
            }
        });
        this.removeByIds(idList);
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    public DbContractVo queryById(String id) {
        DbContract dbContract = this.getById(id);
        if(dbContract==null) {
            return null;
        }
        DbContractVo dbContractVo = new DbContractVo();
        QueryWrapper<DbFile> queryWrapper = new QueryWrapper<>();
        BeanUtils.copyProperties(dbContract,dbContractVo);
        //查找文件路径和id
        if(dbContract.getFileGroupId()!=null){
            queryWrapper.eq("group_id",dbContract.getFileGroupId());
            List<DbFile> list = dbFileService.list(queryWrapper);
            List<String> dbFileList = new ArrayList<>();
            List<String> dbFileIds = new ArrayList<>();
            list.forEach(dbFile -> {
                dbFileList.add(dbFile.getFilePath());
                dbFileIds.add(dbFile.getId());
            });
            dbContractVo.setFilePaths(dbFileList);
            dbContractVo.setFileIds(dbFileIds);
        }

        return dbContractVo;
    }

    //插入文件组id file_group_id
    private void updateFileGroupId(DbContract dbContract){
        if(dbContract.getFileIds()==null||dbContract.getFileIds().isEmpty()){
            this.save(dbContract);
        }else {
            dbContract.setFileGroupId(null);
            this.save(dbContract);
            UpdateWrapper<DbContract> dbContractUpdateWrapper = new UpdateWrapper<>();
            String fileGroupId = "db_contract"+dbContract.getContractId();
            dbContractUpdateWrapper.set("file_group_id",fileGroupId).eq("id",dbContract.getId());
            this.update(dbContract,dbContractUpdateWrapper);
            UpdateWrapper<DbFile> updateWrapper = new UpdateWrapper<>();
            DbFile dbFile = new DbFile();
            updateWrapper.set("group_id", fileGroupId).in("id",dbContract.getFileIds());
            dbFileService.update(dbFile,updateWrapper);
        }
    }
//插入财务表db_finance_manage
    public void insertFinanceManage(DbContract dbContract){
        DbFinanceManage dbFinanceManage = new DbFinanceManage();
        dbFinanceManage.setContractId(dbContract.getContractId())
                .setName(dbContract.getName())
                .setCusName(dbContract.getCusName())
                .setSignatureDate(dbContract.getSignatureDate())
                .setType(dbContract.getType())
                .setContractAmount(dbContract.getContractAmount())
                .setReceivableAmount(dbContract.getContractAmount());
        dbFinanceManageService.save(dbFinanceManage);
    }

    /**
     * 修改回款额度和进度
     */
    @Transactional
    public void updateDbContract(String contractId, BigDecimal sumCount, float paymentProgress){
        // 修改
        LambdaUpdateWrapper<DbContract> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(DbContract::getReturnedAmount, sumCount);
        updateWrapper.set(DbContract::getPaymentProgress, paymentProgress);
        updateWrapper.eq(DbContract::getContractId, contractId);
        this.update(updateWrapper);
    }

    /**
     *查询合同id列表
     *
     * @return
     */
    public List<String> getContractIdList() {
        List<DbContract> list = this.list();
        if(list!=null){
            List<String> contractIdList = new ArrayList<>();
            list.forEach(dbContract -> {
                contractIdList.add(dbContract.getContractId());
            });
            return contractIdList;
        }
        return null;
    }

    @Override
    public ContractStatisticsVo contractSatatistics() {
        Long total = dbContractMapper.selectCount(Wrappers.emptyWrapper());
        List<DbContract> dbContracts = dbContractMapper.selectList(Wrappers.emptyWrapper());
//        总金额求和
        List<BigDecimal> amountList = null;
        if(CollectionUtils.isNotEmpty(dbContracts)){
            amountList = dbContracts.stream()
                    .map(dbContract -> dbContract.getContractAmount())
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
        }
        BigDecimal tolamount = amountList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
//        已返回金额求和
        List<BigDecimal> returnAmountList = null;
        if(CollectionUtils.isNotEmpty(dbContracts)){
            returnAmountList = dbContracts.stream()
                    .map(dbContract -> dbContract.getReturnedAmount())
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
        }
        BigDecimal returnAmount = returnAmountList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal rebackAmount = tolamount.subtract(returnAmount);
        return ContractStatisticsVo.builder().total(total).tolamount(tolamount).rebackAmount(rebackAmount).build();
    }
}
